/**
 * Copyright (C) 2010-2016 eBusiness Information, Excilys Group
 * Copyright (C) 2016-2020 the AndroidAnnotations project
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed To in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ohosannotations.holder;

import com.helger.jcodemodel.IJExpression;
import com.helger.jcodemodel.JBlock;
import com.helger.jcodemodel.JFieldVar;
import com.helger.jcodemodel.JMethod;
import com.helger.jcodemodel.JVar;

import org.ohosannotations.OhosAnnotationsEnvironment;

import javax.lang.model.element.TypeElement;

import static com.helger.jcodemodel.JExpr._new;
import static com.helger.jcodemodel.JExpr._null;
import static com.helger.jcodemodel.JMod.PRIVATE;
import static org.ohosannotations.helper.ModelConstants.generationSuffix;

/**
 * ecomponent持有人
 *
 * @author dev
 * @since 2021-07-22
 */
public abstract class EComponentHolder extends BaseGeneratedClassHolder {
    /**
     * 上下文裁判
     */
    protected IJExpression contextRef;
    /**
     * 根部分裁判
     */
    protected IJExpression rootFractionRef;
    /**
     * 初始化
     */
    protected JMethod init;

    private JBlock initBodyBeforeInjectionBlock;
    private JBlock initBodyInjectionBlock;
    private JBlock initBodyAfterInjectionBlock;
    private JVar resourcesRef;
    private JFieldVar powerManagerRef;

    /**
     * ecomponent持有人
     *
     * @param environment 环境
     * @param annotatedElement 带注释的元素
     * @throws Exception 异常
     */
    public EComponentHolder(OhosAnnotationsEnvironment environment, TypeElement annotatedElement) throws Exception {
        super(environment, annotatedElement);
    }

    /**
     * 获得上下文裁判
     *
     * @return {@link IJExpression}
     */
    public IJExpression getContextRef() {
        if (contextRef == null) {
            setContextRef();
        }
        return contextRef;
    }

    /**
     * 设置上下文裁判
     */
    protected abstract void setContextRef();

    /**
     * 得到根片段裁判
     *
     * @return {@link IJExpression}
     */
    public IJExpression getRootFragmentRef() {
        if (rootFractionRef == null) {
            setRootFragmentRef();
        }
        return rootFractionRef;
    }

    /**
     * 设置根片段裁判
     */
    protected void setRootFragmentRef() {
        rootFractionRef = _null();
    }

    /**
     * 获取初始化
     *
     * @return {@link JMethod}
     */
    public JMethod getInit() {
        if (init == null) {
            setInit();
        }
        return init;
    }

    /**
     * setInit
     */
    protected abstract void setInit();

    /**
     * getInitBody
     *
     * @return getInit
     */
    public JBlock getInitBody() {
        return getInit().body();
    }

    /**
     * getInitBodyInjectionBlock
     *
     * @return initBodyInjectionBlock
     */
    public JBlock getInitBodyInjectionBlock() {
        if (initBodyInjectionBlock == null) {
            setInitBodyBlocks();
        }

        return initBodyInjectionBlock;
    }

    /**
     * getInitBodyAfterInjectionBlock
     *
     * @return initBodyAfterInjectionBlock
     */
    public JBlock getInitBodyAfterInjectionBlock() {
        if (initBodyAfterInjectionBlock == null) {
            setInitBodyBlocks();
        }

        return initBodyAfterInjectionBlock;
    }

    /**
     * getInitBodyBeforeInjectionBlock
     *
     * @return initBodyBeforeInjectionBlock
     */
    public JBlock getInitBodyBeforeInjectionBlock() {
        if (initBodyBeforeInjectionBlock == null) {
            setInitBodyBlocks();
        }

        return initBodyBeforeInjectionBlock;
    }

    /**
     * setInitBodyBlocks
     */
    private void setInitBodyBlocks() {
        initBodyBeforeInjectionBlock = getInitBody().blockVirtual();
        initBodyInjectionBlock = getInitBody().blockVirtual();
        initBodyAfterInjectionBlock = getInitBody().blockVirtual();
    }

    /**
     * getResourcesRef
     *
     * @return resourcesRef
     */
    public JVar getResourcesRef() {
        if (resourcesRef == null) {
            setResourcesRef();
        }
        return resourcesRef;
    }

    /**
     * setResourcesRef
     */
    private void setResourcesRef() {
        resourcesRef = getInitBodyBeforeInjectionBlock().decl(getClasses().RESOURCES,
            "resources" + generationSuffix(), getContextRef().invoke("getResourceManager"));
    }

    /**
     * getPowerManagerRef
     *
     * @return powerManagerRef
     */
    public JFieldVar getPowerManagerRef() {
        if (powerManagerRef == null) {
            setPowerManagerRef();
        }

        return powerManagerRef;
    }

    /**
     * setPowerManagerRef
     */
    private void setPowerManagerRef() {
        JBlock methodBody = getInitBodyInjectionBlock();
        powerManagerRef = getGeneratedClass().field(PRIVATE, getClasses().POWER_MANAGER,
            "powerManager" + generationSuffix());
        methodBody.assign(powerManagerRef, _new(getClasses().POWER_MANAGER));
    }
}
